<template>
  <div class="home-wrap">
    <div class="tool-wrap">
      <el-button @click="handleRefresh">刷新</el-button>
      <el-button type="primary" @click="handleAddTab">新建命名空间</el-button>
      <el-button type="success" @click="handleAddTask">新建流水线</el-button>
      <el-button type="danger" @click="handleDeleteBatchTask(null)">删除流水线</el-button>
    </div>
    <div class="task-wrap">
      <el-tabs
          class="task-tabs-wrap"
          type="border-card"
          v-model="currentTab"
          closable
          @tab-remove="removeTab"
          @tab-change="tabChange"
      >
        <el-tab-pane class="task-tabs-content" v-for="item in tabs" :key="item.id" :label="item.name" :name="item.id">
          <el-table v-if="taskList && taskList.records.length > 0"
                    :data="taskList?.records"
                    v-loading="tableLoading"
                    :show-overflow-tooltip="true"
                    @selection-change="handleSelectionChange"
          >
            <el-table-column type="selection" width="30"/>
            <el-table-column prop="name" label="流水线名称" width="150">
              <template #default="scope">
                <el-link :underline="false">
                  <h4 class="task-tabs-title" @click="handleToRunFlow(scope.row.id)">{{ scope.row.name }}</h4>
                </el-link>
              </template>
            </el-table-column>
            <el-table-column prop="lastStatus" label="最近运行状态" width="120" align="center">
              <template #default="scope">
                <el-tag v-if="scope.row.lastStatus"
                        effect="dark"
                        :type="getTaskStatusTagType(scope.row.lastStatus as TaskStatus)"
                        round
                >
                  {{ taskStatusTextMap[scope.row.lastStatus as TaskStatus] }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="lastMsg" label="触发信息" min-width="100"/>
            <el-table-column prop="lastBranch" label="操作分支" min-width="100"/>
            <el-table-column prop="lastOperator" label="操作人" min-width="100"/>
            <el-table-column prop="lastTime" label="最近操作时间" min-width="180"/>
            <el-table-column fixed="right" label="操作" width="250">
              <template #default="scope">
                <el-tooltip
                    effect="dark"
                    content="运行"
                    placement="bottom"
                >
                  <el-button type="success" :icon="VideoPlay" circle @click="handleToRunFlow(scope.row.id)"/>
                </el-tooltip>
                <el-tooltip
                    effect="dark"
                    content="设置运行流程"
                    placement="bottom"
                >
                  <el-button type="warning" :icon="Edit" circle @click="handleToEditFlow(scope.row.id)"/>
                </el-tooltip>
                <el-tooltip
                    effect="dark"
                    content="编辑基本信息"
                    placement="bottom"
                >
                  <el-button type="primary" :icon="Setting" circle @click="handleEditTask(scope.row)"/>
                </el-tooltip>
                <el-tooltip
                    effect="dark"
                    content="运行记录"
                    placement="bottom"
                >
                  <el-button type="info" :icon="Histogram" circle @click="handleHis(scope.row.id)"/>
                </el-tooltip>
                <el-tooltip
                    effect="dark"
                    content="删除"
                    placement="bottom"
                >
                  <el-button type="danger" :icon="Delete" circle @click="handleDeleteBatchTask(scope.row.id)"/>
                </el-tooltip>
              </template>
            </el-table-column>
          </el-table>
          <el-empty v-else :description="defaultTip"/>
        </el-tab-pane>
      </el-tabs>
    </div>

    <el-dialog v-model="dialogVisible"
               title="添加命名空间"
               :center="true"
               :width="500"
    >
      <el-form>
        <el-form-item label="命名空间名称">
          <el-input v-model="newName" autocomplete="off" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="handleAddTabConfirm">确 定</el-button>
        </div>
      </template>
    </el-dialog>

    <el-dialog v-model="taskDialog"
               :title="taskForm.edit ? '编辑流水线' : '添加流水线'"
               :center="true"
               :width="500"
    >
      <el-form :model="taskForm">
        <el-form-item label="流水线名称" label-width="140px">
          <el-input v-model="taskForm.name" autocomplete="off"/>
        </el-form-item>
        <el-form-item label="命名空间" label-width="140px">
          <el-select v-model="taskForm.namespace" placeholder="请选择命名空间">
            <el-option v-for="item in tabs" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="taskDialog = false">取 消</el-button>
          <el-button type="primary" @click="handleAddTaskConfirm">确 定</el-button>
        </div>
      </template>
    </el-dialog>

    <el-drawer v-model="drawerFlag" direction="rtl" size="700" :with-header="false">
      <el-table :data="hisData? hisData.records : []" height="calc(100vh - 100px)" v-loading="hisLoading">
        <el-table-column width="90" label="构建序号" fixed>
          <template #default="scope">
            <el-tooltip effect="light" content="查看日志" placement="top-start">
              <span style="color: #409EFF; cursor: pointer;" @click="openHistoryLog(scope.row)">#{{ scope.row.batchId }}</span>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column width="70" label="状态">
          <template #default="scope">
            <el-tag v-if="scope.row.status"
                    effect="dark"
                    :type="getTaskStatusTagType(scope.row.status as TaskStatus)"
                    round
            >
              {{ taskStatusTextMap[scope.row.status as TaskStatus] }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column width="100" label="分支">
          <template #default="scope">
            <el-link :underline="false" style="color: #409EFF;" :icon="Share">{{  scope.row.gitBranch }}</el-link>
          </template>
        </el-table-column>
        <el-table-column property="gitMsg" label="提交信息" />
        <el-table-column width="180" property="createTime" label="开始时间" />
      </el-table>
      <el-pagination
          v-model:current-page="currentPage"
          :page-size="pageSize"
          layout="total, prev, pager, next"
          :total="hisData? hisData.totalRow : 0"
          @current-change="handleCurrentChange"
      />
    </el-drawer>

    <el-dialog
        v-model="logShow"
        :title="logTitle"
        fullscreen
        :before-close="handleLogClose"
    >
      <div v-loading="logLoading" class="his-log">
        <p v-for="(item,index) in logList" :key="index">{{ item }}</p>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="handleLogClose">关闭</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import {onMounted, ref} from "vue";
import type { TabPaneName } from 'element-plus'
import {taskNamespaceList, TaskNamespace, addNamespace, deleteNamespace, getTaskList,
  TaskData, addTask, deleteBatchTask, AddTaskData, getTaskHisList, TaskHisData, getHisLog
} from "@/api/TaskApi.ts"
import {Edit, Delete, VideoPlay, Setting, Histogram, Share} from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus'
import {Page} from "@/data/PageData.ts";
import {taskStatusTextMap, taskStatusTagTypeMap, TaskStatus} from "@/enum/TaskStatus.ts"
import router from "@/router";

const defaultTip = ref<string>('暂无流水线，快去新增吧')
const currentTab = ref<string>('default')
const tabs = ref<Array<TaskNamespace>>([])
const dialogVisible = ref<boolean>(false)
const newName = ref<string>('')
const taskDialog = ref<boolean>(false)
const taskList = ref<Page<TaskData>>()
const tableLoading = ref<boolean>(false)
const taskForm = ref<AddTaskData>({name: '', namespace: '', edit: false, id: ''})
const multipleSelection = ref<Array<TaskData>>([])
const drawerFlag = ref<boolean>(false)
const hisData = ref<Page<TaskHisData>>()
const hisLoading = ref<boolean>(false)
const pageSize = ref<number>(10)
const currentPage = ref<number>(1)
const currentTaskId = ref<string>('')
const logShow = ref<boolean>(false)
const logTitle = ref<string>('')
const logLoading = ref<boolean>(false)
const logList = ref<Array<string>>([])

const handleAddTab = () => {
  newName.value = ''
  dialogVisible.value = true
}

const handleAddTabConfirm = async () => {
  let rs = await addNamespace(newName.value)
  if(rs.data){
    tabs.value.push({
      id: rs.data.id,
      name: rs.data.name
    })
    currentTab.value = rs.data.id
    dialogVisible.value = false
  }
}

const removeTab = async (id:TabPaneName) => {
  let rs = await deleteNamespace(id as string)
  if(rs.code !== '200'){
    return
  }
  let activeId = currentTab.value
  if (activeId === id) {
    tabs.value.forEach((tab, index) => {
      if (tab.id === id) {
        const nextTab = tabs.value[index + 1] || tabs.value[index - 1]
        if (nextTab) {
          activeId = nextTab.id
        }
      }
    })
  }
  currentTab.value = activeId
  tabs.value = tabs.value.filter((tab) => tab.id !== id)
}

onMounted(() => {
  getTabList()
})

async function getTabList(){
  const loading = getLoading('数据加载中...')
  let rs = await taskNamespaceList()
  loading.close()
  tabs.value = rs.data ? rs.data : []
  if(tabs.value.length > 0){
    currentTab.value = tabs.value[0].id
    await handleTaskList(currentTab.value)
  }
}

const getLoading = (msg:string):any  =>{
  return ElLoading.service({
    lock: true,
    text: msg,
    background: 'rgba(0, 0, 0, 0.7)',
  })
}

const handleTaskList = async (id:string) => {
  tableLoading.value = true
  let res = await getTaskList(id)
  tableLoading.value = false
  if(res.data){
    taskList.value = res.data
  }
}

const handleAddTask = () => {
  taskForm.value = { name: '', namespace: '', edit: false, id: ''}
  taskDialog.value = true
}

const handleEditTask = (row:TaskData) => {
  taskForm.value = { name: row.name, namespace: row.namespace, edit: true, id: row.id}
  taskDialog.value = true
}

const handleAddTaskConfirm = async () => {
  let rs = await addTask(taskForm.value)
  if(rs.code === '200'){
    await handleTaskList(taskForm.value.namespace)
    currentTab.value = taskForm.value.namespace
    taskDialog.value = false
  }
}

const tabChange = async (id:TabPaneName) => {
  await handleTaskList(id as string)
}

const handleSelectionChange = (val: TaskData[]) => {
  multipleSelection.value = val
}

const handleDeleteBatchTask = (id:string | null) => {
  ElMessageBox.confirm('是否要删除流水线？',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
      }
  ).then(async () => {
    let list = []
    if(id){
      list = [id]
    }else{
      if(multipleSelection.value.length <= 0){
        ElMessage.error('请先选择要删除的流水线')
        return
      }
      list = multipleSelection.value.map((item) => item.id)
    }
    let rs = await deleteBatchTask(list)
    if(rs.code !== '200'){
      return
    }
    await handleTaskList(currentTab.value)
  }).catch(() => {})
}

const handleRefresh = async () => {
  await handleTaskList(currentTab.value)
}

const handleToEditFlow = (id:string) => {
  router.push({ name: 'editFlow', query: {id: id}})
}

const handleToRunFlow = (id:string) => {
  router.push({ name: 'runFlow', query: {id: id}})
}

const getTaskStatusTagType = (status:TaskStatus): any => {
  return taskStatusTagTypeMap[status]
}

const handleHis = (taskId:string) => {
  drawerFlag.value = true
  currentTaskId.value = taskId
  currentPage.value = 1
  queryTaskHis()
}

const queryTaskHis = async () => {
  hisLoading.value = true
  const rs = await getTaskHisList({taskId: currentTaskId.value, pageSize: pageSize.value, pageNum: currentPage.value})
  hisData.value = rs.data
  hisLoading.value = false
}

const handleCurrentChange = (val: number) => {
  currentPage.value = val
  queryTaskHis()
}

const handleLogClose = () => {
  logShow.value = false
  logList.value = []
}

const openHistoryLog = async (data:TaskHisData) => {
  logShow.value = true
  logLoading.value = true
  logTitle.value = `日志文件名称：${data.logFile}`
  const rs = await getHisLog(data.taskId, data.batchId)
  logLoading.value = false
  logList.value = rs.data
}
</script>

<style lang="less" scoped>
.home-wrap{
  padding: 20px;

  .tool-wrap{
    margin-top: 30px;
    display: flex;
    justify-content: flex-end;
  }

  .task-wrap{
    margin-top: 20px;

    .task-tabs-wrap{
      border-radius: 4px;

      .task-tabs-content{
        min-height: 550px;

        .task-tabs-title{
          color: #409eff;
        }
      }
    }
  }

  .his-log{
    height: calc(100vh - 120px);
    background-color: #000000;
    color: #FFFFFF;
    padding: 10px;
    border-radius: 5px;
    overflow-y: scroll;
  }
}
</style>